package com.lazydong.apiforward.client.gui.pages.log;

import cn.hutool.core.util.StrUtil;
import com.lazydong.apiforward.client.framework.PageAbility;
import com.lazydong.apiforward.client.framework.PageContainer;
import com.lazydong.apiforward.client.framework.PageEvent;
import com.lazydong.apiforward.client.framework.PageInfo;
import com.lazydong.apiforward.client.framework.annotation.ChildPage;
import com.lazydong.apiforward.client.gui.enums.PageEventEnum;
import com.lazydong.apiforward.client.gui.enums.PageInfoEnum;
import com.lazydong.gui.layout.Margin;
import com.lazydong.gui.layout.Size;
import com.lazydong.gui.layout.linear.LinearLayoutUtil;
import com.lazydong.gui.layout.linear.VLinearAlign;

import javax.swing.*;
import javax.swing.text.Document;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;

@ChildPage
public class LogShowPage extends PageAbility<Object> {
    private static JTextArea logShowArea;

    private static final AtomicInteger logShowLine = new AtomicInteger(100);

    private static final AtomicBoolean isPrintLog = new AtomicBoolean(true);

    private static final JTextField lingCountField = new JTextField();

    private static final JButton lingCountUpdate = new JButton();

    private static final JButton clean = new JButton();

    private static final JButton pause = new JButton();

    @Override
    public PageInfo getPageInfoEnum() {
        return PageInfoEnum.LOG_SHOW;
    }

    @Override
    public int getOrder() {
        return 0;
    }

    @Override
    public void initConfig() {

    }

    @Override
    public Object loadConfig() {
        return null;
    }

    @Override
    public void buildPage(JPanel parentJPanel, Object config) {
        LinearLayoutUtil.setVLayout(parentJPanel, VLinearAlign.Centre);
        // 日志展示相关设置
        JPanel logSetting = new JPanel();
        LinearLayoutUtil.addComponent(parentJPanel, logSetting, Size.ofHeightRatio(4), Margin.ofTopRatio(1));
        logSetting(logSetting);

        JPanel logShow = new JPanel();
        LinearLayoutUtil.addComponent(parentJPanel, logShow, Size.ofHeightRatio(87));
        logShow(logShow);
    }

    private void logSetting(JPanel logSetting) {
        LinearLayoutUtil.setHLayout(logSetting);
        JLabel line = new JLabel("日志最大行数");
        LinearLayoutUtil.addComponent(logSetting, line, Size.ofRatio(14, 90), Margin.ofLeftRatio(2));

        lingCountField.setEnabled(false);
        lingCountField.setText(String.valueOf(logShowLine.get()));
        LinearLayoutUtil.addComponent(logSetting, lingCountField, Size.ofRatio(6, 90));

        LogButtonListener logButtonListener = new LogButtonListener();

        lingCountUpdate.setText("修改");
        lingCountUpdate.setActionCommand("lingCountUpdate");
        lingCountUpdate.addActionListener(logButtonListener);
        LinearLayoutUtil.addComponent(logSetting, lingCountUpdate, Size.ofRatio(11, 90));

        clean.setText("日志清空");
        clean.setActionCommand("clean");
        clean.addActionListener(logButtonListener);
        LinearLayoutUtil.addComponent(logSetting, clean, Size.ofRatio(15, 90), Margin.ofLeftRatio(30));

        pause.setText("日志输出暂停");
        pause.setActionCommand("pause");
        pause.addActionListener(logButtonListener);
        LinearLayoutUtil.addComponent(logSetting, pause, Size.ofRatio(20, 90), Margin.ofLeftRatio(1));
    }

    private void logShow(JPanel logShow) {
        LinearLayoutUtil.setHLayout(logShow);
        logShowArea = new JTextArea();
        logShowArea.setLineWrap(true);
        logShowArea.setEditable(false);
        logShowArea.setRows(39);
        JScrollPane scrollPane = new JScrollPane(logShowArea);

        LinearLayoutUtil.addComponent(logShow, scrollPane, Size.ofRatio(100, 100));
    }

    /**
     * 追加日志
     *
     * @param text text
     */
    private static void appendLogShow(String text) {
        if (!isPrintLog.get()) {
            return;
        }
        logShowArea.append(text + System.lineSeparator());
        logShowArea.setCaretPosition(logShowArea.getDocument().getLength());
        removeFirstNLines();
    }

    private static void cleanLogShow() {
        logShowArea.setText("");
    }

    /**
     * 删除第一行的数据
     */
    private static void removeFirstNLines() {
        if (logShowLine.get() <= 0) {
            return;
        }
        Document doc = logShowArea.getDocument();
        int totalLines;
        totalLines = logShowArea.getLineCount();
        if (totalLines <= logShowLine.get()) {
            return;
        }
        try {
            int lineCount = logShowArea.getLineCount();
            int n = lineCount - logShowLine.get();
            // 获取第n行结尾时的偏移量
            int endOffset = logShowArea.getLineEndOffset(n);

            // 删除0-endOffset的数据，来实现删除第一行数据
            doc.remove(0, endOffset);
        } catch (Exception ex) {
            System.out.println(ex.getMessage());
        }
    }

    @Override
    public void afterBuildPage() {
        lingCountUpdate.setEnabled(false);
        pause.setEnabled(false);
        clean.setEnabled(false);
    }

    @Override
    public void afterServiceStart() {
        lingCountUpdate.setEnabled(true);
        pause.setEnabled(true);
        clean.setEnabled(true);
    }

    @Override
    public void monitorEvent(PageEvent pageEvent, String text) {
        if (pageEvent.getCode().equals(PageEventEnum.LOG_SHOW.getCode())) {
            appendLogShow(text);
        }
    }

    /**
     * 按钮监听器
     */
    private static class LogButtonListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent event) {
            String actionCommand = event.getActionCommand();
            if (StrUtil.equals("lingCountUpdate", actionCommand)) {
                lingCountField.setEnabled(true);
                lingCountUpdate.setText("确认");
                lingCountUpdate.setActionCommand("lingCountConfirm");
                return;
            }
            if (StrUtil.equals("lingCountConfirm", actionCommand)) {
                lingCountField.setEnabled(false);
                lingCountUpdate.setText("修改");
                lingCountUpdate.setActionCommand("lingCountUpdate");
                String text = lingCountField.getText();
                logShowLine.set(Integer.parseInt(text));
                return;
            }
            if (StrUtil.equals("clean", actionCommand)) {
                cleanLogShow();
            }
            if (StrUtil.equals("pause", actionCommand)) {
                isPrintLog.set(false);
                pause.setText("日志输出继续");
                pause.setActionCommand("continue");
                PageContainer.sendAsyncEvent(PageEventEnum.MAIN_PAGE_TIP, "日志输出已暂停");
            }
            if (StrUtil.equals("continue", actionCommand)) {
                isPrintLog.set(true);
                pause.setText("日志输出暂停");
                pause.setActionCommand("pause");
                PageContainer.sendAsyncEvent(PageEventEnum.MAIN_PAGE_TIP, "日志输出继续");
            }
        }
    }
}
